﻿using System.Linq;
using CardPlay.Model.CardModel;
using CardPlay.Model.GameModel;
using CardPlay.Model.GameModel.Actions;
using CardPlay.Model.GameModel.Presentation;
using CardPlay.Model.Layout;

namespace CardPlay.DemoPack.Games
{
    [Game("CE01AE9F-AFBC-45D7-8FE2-28D8D562DEC3", LevelOfDifficulty.Easy, LevelOfSkill.ChanceOnly, DurationOfPlay.LessThan5Minutes)]
    public class Simplex : StandardCardGame
    {
        public Simplex()
        {
            MaximumDeals = 1;
            CardsPerDeal = 1;

            TotalFoundations = 0;
            TotalTableaus = 9;
            TableauBuildSequence = new CardFaceSequenceSpecification(SuitSequence.DontCare, RankSequence.SameRank);
        }

        public override ILayoutSite CreatePresentation(IPresentationContext presentation)
        {
            var root = presentation.CreateColumnLayout();
            root.Add(presentation.CreateStockWasteLayout(this));

            var tableau = presentation.CreateRowLayout();
            root.Add(tableau);

            presentation.AddTableauPiles(this, tableau);

            return root;
        }

        public override int PercentComplete
        {
            get
            {
                var initialCount = CardsAtStart;
                var currentCount = CardPiles.Aggregate(0, (total, pile) => total + pile.Count);

                return 100 - (100 * currentCount) / initialCount;
            }
        }

        protected override bool IsComplete
        {
            get { return CardPiles.All(pile => pile.IsEmpty); }
        }

        protected override IDealAction CreateDealScript()
        {
            var sequence = new DealSequence();

            foreach (var pile in PilesNamed(AnyTableau))
                sequence.Add(new DealCardAction(pile.Name, face => this.NonEmptyPilesNamed(AnyTableau).All(p => p.TopCard.Rank != face.Rank)) { Orientation = CardOrientation.FaceUp });

            sequence.Add(new DealSequence(Stock, DealExpression.ForRemainingCards(CardOrientation.FaceDown)));
            return sequence;
        }

        protected override void PrepareDealScript(DealScript script)
        {
        }

        protected override void OnTransactionEnding()
        {
            foreach (var pile in PilesNamed(AnyTableau).Where(pile => pile.Count == CardFace.SuitsPerDeck))
                Execute(new RemovePileAction(this, pile.Bottom));

            this.FillFromStockEmptyPilesMatching(AnyTableau);
        }
    }
}
